package cn.jiemusic.controller;

import cn.hutool.core.util.RandomUtil;
import cn.jiemusic.common.CustomException;
import cn.jiemusic.common.R;
import cn.jiemusic.domain.dto.EmailCodeDto;
import cn.jiemusic.domain.po.User;
import cn.jiemusic.service.UserService;
import cn.jiemusic.utils.CodeUtils;
import cn.jiemusic.utils.MailUtils;
import cn.jiemusic.utils.RangeResource;
import cn.jiemusic.utils.TransferUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

@RestController
@RequestMapping("/common")
@Slf4j
public class CommonController {
    @Autowired
    private MailUtils mailUtils;
    @Value("${project-config.base-path}")
    private String basePath;
    @Autowired
    private UserService userService;

    @GetMapping("/code")
    public R<String> createCode(HttpServletRequest req) throws IOException {
        log.info("正在生成验证码...");
        String lineCaptcha = CodeUtils.getLineCaptcha(req);
        return R.success(lineCaptcha);
    }

    @GetMapping("/check-code")
    public R<String> checkCode(HttpServletRequest req, String code) {
        CodeUtils.checkCode(req, code);
        return R.success("验证成功");
    }

    @PostMapping("/email-code")
    public R<String> emailCode(HttpServletRequest req, @RequestBody EmailCodeDto codeDto) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getEmail, codeDto.getEmail());
        queryWrapper.eq(User::getUsername, codeDto.getUsername());
        if (userService.count(queryWrapper) != 1) throw new CustomException("邮箱与用户名不匹配");

        String eCode = RandomUtil.randomString(4);

        //存入请求
        HttpSession session = req.getSession();
        session.setAttribute("eCode", eCode);
        req.getSession().setAttribute("code", codeDto.getCode());

        String temp = "你的验证码是：" + eCode;
        mailUtils.sendEMail(codeDto.getEmail(), temp, temp);

        return R.success("邮件发送成功");
    }

    @PostMapping("/check-eCode")
    public R<String> checkECode(HttpServletRequest req, @RequestBody EmailCodeDto codeDto) {
        CodeUtils.checkCode(req, codeDto.getCode());
        CodeUtils.checkECode(req, codeDto.getEmailCode());
        return R.success("验证成功");
    }

    @GetMapping("/audio/{id}")
    public ResponseEntity<Resource> getAudio(
            @RequestHeader(value = "Range", required = false) String rangeHeader,
            @PathVariable String id) throws IOException {
        log.info("请求音频文件，ID: {}", id);

        // 获取音频文件
        File audioFile = new File(TransferUtils.getAPathById(basePath, id, "audio"));
        if (!audioFile.exists()) {
            return ResponseEntity.status(HttpStatus.NOT_FOUND).body(null);
        }

        // 使用 FileSystemResource 读取文件
        Resource fileResource = new FileSystemResource(audioFile);
        long fileLength = audioFile.length();

        if (rangeHeader == null) {
            // 如果没有 Range 请求头，直接返回整个文件
            return ResponseEntity.ok()
                    .contentType(MediaType.APPLICATION_OCTET_STREAM)
                    .contentLength(fileLength)
                    .body(fileResource);
        }

        // 解析 Range 请求头
        long start = 0;
        long end = fileLength - 1; // 默认返回整个文件
        if (rangeHeader.startsWith("bytes=")) {
            String[] ranges = rangeHeader.substring(6).split("-");
            start = Long.parseLong(ranges[0]); // 起始位置
            if (ranges.length > 1) {
                end = Long.parseLong(ranges[1]); // 结束位置
            }
        }

        // 确保范围合法
        if (start > end || end >= fileLength) {
            return ResponseEntity.status(HttpStatus.REQUESTED_RANGE_NOT_SATISFIABLE)
                    .header("Content-Range", "bytes */" + fileLength)
                    .build();
        }

        // 创建分段资源
        RangeResource rangeResource = new RangeResource(fileResource, start, end);

        // 返回带分段信息的响应
        return ResponseEntity.status(HttpStatus.PARTIAL_CONTENT)
                .contentType(MediaType.APPLICATION_OCTET_STREAM)
                .header("Content-Range", "bytes " + start + "-" + end + "/" + fileLength)
                .contentLength(end - start + 1)
                .body(rangeResource);
    }


    @GetMapping("/cover/{id}")
    public void download(HttpServletResponse response, @PathVariable String id) {

        try {
            File file = new File(TransferUtils.getAPathById(basePath, id, "cover"));
            FileInputStream fileInputStream = new FileInputStream(file);
            ServletOutputStream outputStream = response.getOutputStream();

            // 根据文件扩展名设置响应的内容类型
            int len;
            byte[] bytes = new byte[1024];
            while ((len = fileInputStream.read(bytes)) != -1) {
                outputStream.write(bytes, 0, len);
                outputStream.flush();
            }

            outputStream.close();
            fileInputStream.close();

        } catch (Exception e) {
            log.error(e.getMessage());
        }
    }
}
